import ctypes
import os
import subprocess

def resolve_name(source):
    # Get the actual name of the file, after reparse points and symlinks are
    # taken into account.
    GENERIC_READ = 0x80000000
    FILE_SHARE_READ = 0x1
    OPEN_EXISTING = 0x3
    FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
    handle = ctypes.windll.kernel32.CreateFileA(source,
                                                GENERIC_READ,
                                                FILE_SHARE_READ,
                                                None,
                                                OPEN_EXISTING,
                                                FILE_FLAG_BACKUP_SEMANTICS,
                                                None)
    # get the target
    FILE_NAME_NORMALIZED = 0x0
    FILE_NAME_OPENED = 0x8
    buff = ctypes.create_string_buffer(1024)
    res = ctypes.windll.kernel32.GetFinalPathNameByHandleA(handle,
                                                           buff,
                                                           ctypes.sizeof(buff),
                                                           FILE_NAME_NORMALIZED)
    target = buff.value
    ctypes.windll.kernel32.CloseHandle(handle)
    return target

def search_up(path, target):
    while True:
        if os.path.exists(os.path.join(path, target)):
            return True
        npath = os.path.dirname(path)
        if npath == path:
            break
        path = npath
    return False

Import('qt_env')

env = qt_env.Clone()

modules = [ 
    'Core', 
    'Gui', 
    'Network', 
    'Script', 
    'Sql', 
    'WebKit', 
    'Xml', 
    'XmlPatterns',
    'Declarative'
]

if env['QT_MAJOR_VERSION'] > 4:
    modules += [ 
        'Widgets',
        'Qml',
        'WebKitWidgets'
    ]

env.EnableQtModules(*modules)

env.Uic(env.Glob('*.ui'))

env.RequireLibraries('uibase', 'shared', 'bsatk', 'esptk')

env.AppendUnique(LIBS = [
    'shell32',
    'user32',
    'ole32',
    'advapi32',
    'gdi32',
    'shlwapi',
    'Psapi',
    'Version'
])

# We have to 'persuade' moc to generate certain other targets and inject them
# into the list of cpps
other_sources = env.AddExtraMoc(env.Glob('*.h'))

for file in env.Glob('*.rc'):
    other_sources.append(env.RES(file))

# Note the order of this is important, or you can pick up the wrong report.h...
# Doing appendunique seems to throw the moc code into a tizzy
env['CPPPATH'] += [
    '../archive',
    '../plugins/gamefeatures',
    '.',            # Why is this necessary?
    '${LOOTPATH}',
    '${BOOSTPATH}',
]

#########################FUDGE###############################
env['CPPPATH'] += [
    '../plugins/gameGamebryo',
    ]
#############################################################

env.AppendUnique(CPPDEFINES = [
    '_UNICODE',
    '_CRT_SECURE_NO_WARNINGS',
    '_SCL_SECURE_NO_WARNINGS',
    'BOOST_DISABLE_ASSERTS',
    'NDEBUG',
    'QT_MESSAGELOGCONTEXT'
])

# Boost produces very long names with msvc truncates. Doesn't seem to cause
# problems.
# Also note to remove the -wd4100 I hacked the boost headers (tagged_argument.hpp)
# appropriately.
env.AppendUnique(CPPFLAGS = [ '-wd4503' ])

env.AppendUnique(LINKFLAGS = [
    '/SUBSYSTEM:WINDOWS',
    '${EXE_MANIFEST_DEPENDENCY}'
])

#  modeltest is optional and it doesn't compile anyway...
cpp_files = [
    x for x in env.Glob('*.cpp', source = True)
        if x.name != 'modeltest.cpp' and x.name != 'aboutdialog.cpp' and \
           not x.name.startswith('moc_') # I think this is a strange bug
]

about_env = env.Clone()
# This is somewhat of a hack until I can work out a way of setting up a build
# with all the repos without using millions of junction points
try:
    target = resolve_name(Dir('.').srcnode().abspath)
    if search_up(target, '.hg'):
        hgid = subprocess.check_output([env['MERCURIAL'], 'id', '-i']).rstrip()
    elif search_up(target, '.git'):
        hgid = subprocess.check_output([env['GIT'], '-C', target, 'describe',
                                                              '--tag']).rstrip()
    else:
        hgid = "Unknown"
except:
    hgid = "Problem determining version"

# FIXME: It'd be much easier to stringify this in the source code
about_env.AppendUnique(CPPDEFINES = [ 'HGID=\\"%s\\"' % hgid ])
other_sources.append(about_env.StaticObject('aboutdialog.cpp'))

env.AppendUnique(LIBPATH = "${ZLIBPATH}/build")
env.AppendUnique(LIBS = 'zlibstatic')

prog = env.Program('ModOrganizer',
                   cpp_files + env.Glob('*.qrc') + other_sources)

env.InstallModule(prog)

for subdir in ('tutorials', 'stylesheets'):
    env.Install(os.path.join(env['INSTALL_PATH'], subdir),
                env.Glob(os.path.join(subdir, '*')))

# FIXME Sort the translations. Except they don't exist on the 1.2 branch

res = env['QT_USED_MODULES']
Return('res')

"""
CONFIG(debug, debug|release) {
} else {
  QMAKE_CXXFLAGS += /Zi /GL
  QMAKE_LFLAGS += /DEBUG /LTCG /OPT:REF /OPT:ICF
}

TRANSLATIONS = organizer_en.ts


QMAKE_POST_LINK += xcopy /y /s /I $$quote($$BASEDIR\\*.qm) $$quote($$DSTDIR)\\translations $$escape_expand(\\n)

"""
